home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SPACE 1
/
SPACE - Library 1 - Volume 1.iso
/
misc~1
/
5
/
osspascl
/
aesvdi.doc
next >
Wrap
Text File
|
1985-11-19
|
12KB
|
272 lines
MAKING GENERIC AES AND VDI CALLS FROM PERSONAL PASCAL
-----------------------------------------------------
As some of you have discovered, because of prior experience with the Atari ST
developer's package, there are a number of calls within the GEM system (AES and
VDI) which are not yet supported by Personal Pascal. Luckily, within the
PASGEM library there are two routines which already support additional calls to
GEM. This document gives you the information you need in order to call these
two generic GEM routines.
AES CALLS
---------
First of all, we are going to tackle AES calls. In the process of explaining
how to call the generalized AES routine, we will be implementing a new call
which is not supported by Pascal. This routine, which is called "graf_mkstate"
in the C bindings, returns the current state of the mouse buttons and the key-
board modifier keys (i.e., alternate, left and right shift keys, and control).
This routine takes four parameters which are the addresses of four two-byte
variables in which to put the mouse and keyboard state information. Since
passing an address in Pascal is equivalent to passing a variable as a VAR
parameter, the declaration of the routine we're going to construct is going
to start like this:
(* Mouse_Key_State - Return the current mouse position and the state of both
the mouse buttons and the keyboard modifier keys. *)
PROCEDURE Mouse_Key_State( VAR x, y, buttons, keys : integer ) ;
Before we start filling in the rest of the procedure, we have to look at how
parameters are passed to the AES. There are four separate areas in which
values are passed to and returned from AES. The first area is the "global
parameter area", where AES stores various parameters it needs to keep around
between calls. Since the application program should not modify these values,
there is no way to access the "global" array from Pascal. The second area is
the "integer input array", in which various integer values may be passed to
AES. Similarly, there is an "integer output array" in which AES passes values
back to the calling program. The fourth and fifth arrays are the "address
input array" and the "address output array". These two areas will contain
address parameters passed to or from AES. The Pascal library keeps track of
the global parameter area, since it must remain intact, but the other arrays
must be declared in your GEM program if you want to make calls to the AES
handler. In order to declare the arrays easily, we will set up their types
first:
TYPE
Pointer = ^char ; (* Just a filler declaration! *)
Int_In_Parms = ARRAY [ 0..15 ] OF integer ;
Int_Out_Parms = ARRAY [ 0..45 ] OF integer ;
Addr_In_Parms = ARRAY [ 0..1 ] OF Pointer ;
Addr_Out_Parms = ARRAY [ 0..0 ] OF Pointer ;
The declaration of "Pointer" is just used to emphasize that the address in and
out parameters are ADDRESSES, and not just numeric values. Notice that the
integer arrays only have lengths 16 and 46, respectively. This is sufficient
for most calls, but if you want to make a call to VDI (see below) which needs
more slots in these arrays, increase the size accordingly. Now that we know
the TYPEs of the local variables we need, we can declare them:
VAR
int_in : Int_In_Parms ;
int_out : Int_Out_Parms ;
addr_in : Addr_In_Parms ;
addr_out : Addr_Out_Parms ;
OK, we're ready to look into the actual routine which we will be calling to
interface to GEM. It takes five parameters. The first is the AES call number,
which is 79 for out "graf_mkstate" call. The next four parameters are just the
arrays which we just declared, passed as VAR parameters. The routine should be
declared EXTERNAL as follows:
PROCEDURE AES_Call( op : integer ;
VAR int_in : Int_In_Parms ; VAR int_out : Int_Out_Parms ;
VAR addr_in : Addr_In_Parms ; VAR addr_out : Addr_Out_Parms ) ;
EXTERNAL ;
Now that we know all of our variables and parameters, and everything the
AES_Call routine is expecting, we can look at what we need to do to actually
perform the GEM call. According to the AES documentation, the "graf_mkstate"
call doesn't expect any parameters, and it returns the results in the "integer
output array" as follows:
int_out[0] -- error code (0 if no error occurred)
int_out[1] -- current mouse x position
int_out[2] -- mouse y position
int_out[3] -- mouse button state
int_out[4] -- keyboard modifier state
We should never get an error with this call, since no parameters are passed in,
so we're going to ignore the error code. This isn't a good idea in general,
but it simplifies our presentation somewhat. The complete code required to
perform the call and return the result values in the proper parameters is as
follows:
BEGIN
AES_Call( 79, int_in, int_out, addr_in, addr_out ) ;
x := int_out[1] ;
y := int_out[2] ;
buttons := int_out[3] ;
keys := int_out[4] ;
END ;
To summarize this section on making AES calls, here is a complete listing of
the Mouse_Key_State routine, without the intervening text:
(* Mouse_Key_State - Return the current mouse position and the state of both
the mouse buttons and the keyboard modifier keys. *)
PROCEDURE Mouse_Key_State( VAR x, y, buttons, keys : integer ) ;
TYPE
Pointer = ^char ; (* Just a filler declaration! *)
Int_In_Parms = ARRAY [ 0..15 ] OF integer ;
Int_Out_Parms = ARRAY [ 0..45 ] OF integer ;
Addr_In_Parms = ARRAY [ 0..1 ] OF Pointer ;
Addr_Out_Parms = ARRAY [ 0..0 ] OF Pointer ;
VAR
int_in : Int_In_Parms ;
int_out : Int_Out_Parms ;
addr_in : Addr_In_Parms ;
addr_out : Addr_Out_Parms ;
PROCEDURE AES_Call( op : integer ;
VAR int_in : Int_In_Parms ; VAR int_out : Int_Out_Parms ;
VAR addr_in : Addr_In_Parms ; VAR addr_out : Addr_Out_Parms ) ;
EXTERNAL ;
BEGIN
AES_Call( 79, int_in, int_out, addr_in, addr_out ) ;
x := int_out[1] ;
y := int_out[2] ;
buttons := int_out[3] ;
keys := int_out[4] ;
END ;
VDI CALLS
---------
Accessing the VDI system is very similar to the discussion of AES calls above.
The only main difference is that, although there is a "global parameter array",
it doesn't need to stay intact. Also, sometimes you need to get return values
in this array. Also, no address parameters are ever passed, but a new type of
value is passed and returned, points. So the TYPE declarations for the various
arrays we need are slightly different:
TYPE
Ctrl_Parms = ARRAY [ 0..11 ] OF integer ;
Int_In_Parms = ARRAY [ 0..15 ] OF integer ;
Int_Out_Parms = ARRAY [ 0..45 ] OF integer ;
Pts_In_Parms = ARRAY [ 0..11 ] OF integer ;
Pts_Out_Parms = ARRAY [ 0..11 ] OF integer ;
For our VDI calling example, we're going to implement the call which allows you
to control the height of text that is drawn using the "Draw_String" call. This
call is known in the VDI documentation as "vst_height", but we're going to
declare it like this:
(* Text_Height - Set the height in pixels of text, when it is drawn using the
Draw_String library call. *)
PROCEDURE Text_Height( height : integer ) ;
Again, we need to declare the variables which we are going to pass to VDI:
VAR
control : Ctrl_Parms ;
int_in : Int_In_Parms ;
int_out : Int_Out_Parms ;
pts_in : Pts_In_Parms ;
pts_out : Pts_Out_Parms ;
The actual generic routine we are going to call to perform VDI operations is
very similar to the AES_Call routine described above. One difference is that
we pass two command numbers instead of one. The second number is only used
when we call the GSX graphics primitives; it is the GSX primitive number which
we want to use. For all non-GSX calls (i.e., most of the time), this second
number will be zero (as it is in this case). Also, there is one additional
parameter, called "translate" in the declaration below, which specifies whether
to translate the points in the "pts_in" and "pts_out" array RELATIVE to the
current origin. What this means is that if you use the Set_Window call to
make a window current, all points passed to or from VDI will be translated
to screen coordinates such that (0,0) is equivalent to the upper left of that
window, PROVIDED the value of "translate" is true. If you don't want such
translation to occur (we don't, in this case, since the "point" we are passing
is actually the height we want!), pass in "false" for this parameter. The
declaration of the generic VDI call is as follows:
PROCEDURE VDI_Call( cmd, sub_cmd : integer ; nints, npts : integer ;
VAR ctrl : Ctrl_Parms ;
VAR int_in : Int_In_Parms ; VAR int_out : Int_Out_Parms ;
VAR pts_in : Pts_In_Parms ; VAR pts_out : Pts_Out_Parms ;
translate : boolean ) ;
EXTERNAL ;
Notice that we must tell VDI the number of integers and points which we are
passing. The particular call we want to use is number 12, "set character
height, absolute mode". It expects two parameters, as follows:
pts_in[0] -- 0 (the value zero)
pts_in[1] -- desired height in pixels
It returns several parameters:
pts_out[0] -- character width selected
pts_out[1] -- character height selected
pts_out[2] -- character cell width selected
pts_out[3] -- character cell height selected
Why are there four return values instead of two? The first two (0 and 1) are
usually SMALLER than the other two, for the following reason. The "character
height" (not cell height) is measured from the baseline (the bottom of capital
letters) to the top line (the top of capitals, including a little space). The
character width is, similarly, measured from the left edge to the right edge
of characters. The "cell width" and "cell height", on the other hand, are
measured from the very bottom to the very top and the very left to the very
right of the "cell" in which a character is drawn. Since some space is put
on all sides of a character, the "cell" measurements are a little larger than
the other measurements. We're actually going to ignore all of the return
parameters, since we just want to set the values and assume they are correct.
The main body of our PROCEDURE is, then:
BEGIN
pts_in[0] := 0 ;
pts_in[1] := height ;
VDI_Call( 12, 0, 0, 2, control, int_in, int_out, pts_in, pts_out, false ) ;
END ;
In order to look at the routine as a whole, here are all the neccessary
declarations and code together, without the intervening text:
(* Text_Height - Set the height in pixels of text, when it is drawn using the
Draw_String library call. *)
PROCEDURE Text_Height( height : integer ) ;
TYPE
Ctrl_Parms = ARRAY [ 0..11 ] OF integer ;
Int_In_Parms = ARRAY [ 0..15 ] OF integer ;
Int_Out_Parms = ARRAY [ 0..45 ] OF integer ;
Pts_In_Parms = ARRAY [ 0..11 ] OF integer ;
Pts_Out_Parms = ARRAY [ 0..11 ] OF integer ;
VAR
control : Ctrl_Parms ;
int_in : Int_In_Parms ;
int_out : Int_Out_Parms ;
pts_in : Pts_In_Parms ;
pts_out : Pts_Out_Parms ;
PROCEDURE VDI_Call( cmd, sub_cmd : integer ; nints, npts : integer ;
VAR ctrl : Ctrl_Parms ;
VAR int_in : Int_In_Parms ; VAR int_out : Int_Out_Parms ;
VAR pts_in : Pts_In_Parms ; VAR pts_out : Pts_Out_Parms ;
translate : boolean ) ;
EXTERNAL ;
BEGIN
pts_in[0] := 0 ;
pts_in[1] := height ;
VDI_Call(12, 0, 0, 2, control, int_in, int_out, pts_in, pts_out, false);
END ;
Press <CR> to continue:
[72477,3703]
AESVDI.DOC 06-Mar-86(07-Mar-86) 11995
12
(R D T):